package com.denlaku.longan.util;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.SneakyThrows;

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.Base64;
import java.util.Optional;

/**
 * @author tianx
 */
public class RsaUtils {
    private static final String ALGORITHM = "RSA";

    private static final Cache<String, KeyPair> CACHE = CacheBuilder
            .newBuilder()
            .expireAfterWrite(Duration.ofHours(25))
            .build();

    /**
     * 获取公钥
     *
     * @return 公钥
     */
    @SneakyThrows
    public static String getPublicKey() {
        String cacheKey = genCacheKey();
        KeyPair keyPair = CACHE.get(cacheKey, RsaUtils::genKeyPair);
        return Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
    }

    private static String genCacheKey() {
        return DateUtil.formatDay();
    }

    @SneakyThrows
    private static KeyPair genKeyPair() {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
        keyGen.initialize(2048, new SecureRandom());
        return keyGen.generateKeyPair();
    }

    @SneakyThrows
    public static String decrypt(String encryptedText) {
        if (encryptedText == null || encryptedText.isEmpty()) {
            return null;
        }
        String cacheKey = genCacheKey();
        KeyPair keyPair = CACHE.getIfPresent(cacheKey);
        PrivateKey privateKey = Optional.ofNullable(keyPair).map(KeyPair::getPrivate).orElse(null);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedText)));
    }

}
